export const getIdMapByListOrTree = (
    data,
    {
        idName = "id",
        childrenName = "children",
        retainOther = false,
        nameMap = {},
    } = {}
) => {
    let out = {};

    if (!data || !data.length) {
        return out;
    }

    data.forEach((v) => {
        if (!v) {
            return;
        }

        const newObject = {};

        if (retainOther) {
            Object.keys(v).forEach((key) => {
                newObject[key] = v[key];
            });
        }

        Object.keys(v).forEach((key) => {
            if (nameMap[key]) {
                newObject[nameMap[key]] = v[key];
            }
        });

        if (v[childrenName] && v[childrenName].length) {
            let childrenMap = getIdMapByListOrTree(v[childrenName], {
                idName,
                childrenName,
                retainOther,
                nameMap,
            });

            Object.assign(out, childrenMap);
        }

        out[v[idName]] = newObject;
    });

    return out;
};

export const arrayItemMove = (data, index, step) => {
    data.splice(index + step, 0, data.splice(index, 1)[0]);
};

export const getIntToStringObject = (data, { deep } = {}) => {
    if (!data || typeof data !== "object") {
        return data;
    }

    let newData = Object.assign(Array.isArray(data) ? [] : {}, data);

    Object.keys(newData).forEach((key) => {
        if (typeof newData[key] === "number") {
            newData[key] = String(newData[key]);
        } else if (deep && typeof newData[key] === "object") {
            newData[key] = getIntToStringObject(newData[key]);
        }
    });

    return newData;
};

export const transArrayToTree = (data, config = {}) => {
    let {
        idName = "id",
        childrenName = "children",
        parentName = "parent",
        parentId = "-1",
    } = config;

    if (!data) {
        return;
    }

    return data
        .map((v) => {
            if (!v || v[parentName] !== parentId) {
                return;
            }

            let out = { ...v };

            let children = transArrayToTree(data, {
                ...config,
                parentId: v[idName],
            });

            if (children || children.length) {
                out[childrenName] = children;
            }

            return out;
        })
        .filter((v) => v);
};

export const renameTreeField = (
    data,
    {
        childrenName = "children",
        retainOther = false,
        nameMap = {
            id: "value",
            name: "label",
            children: "children",
        },
    } = {}
) => {
    if (!data) {
        // !data.length
        return;
    }

    return data
        .map((v) => {
            if (!v) {
                return;
            }

            const newObject = {};

            if (retainOther) {
                Object.keys(v).forEach((key) => {
                    newObject[key] = v[key];
                });
            }

            Object.keys(nameMap).forEach((key) => {
                if (!Object.hasOwnProperty.call(v, key)) {
                    v[key] = false;
                }
            });

            Object.keys(v).forEach((key) => {
                if (nameMap[key]) {
                    if (typeof nameMap[key] === "function") {
                        let temp = nameMap[key](newObject[key], newObject);
                        if (typeof temp.key === "string") {
                            newObject[temp.key] = temp.value;
                        } else if (Array.isArray(temp.key)) {
                            temp.key.forEach(
                                (key) => (newObject[key] = temp.value)
                            );
                        } else if (typeof temp.key === "object") {
                            Object.keys(temp.key).forEach((key) => {
                                newObject[key] = temp.key[key];
                            });
                        }
                    } else {
                        newObject[nameMap[key]] = v[key];
                    }
                }
            });

            if (v[childrenName] && v[childrenName].length) {
                newObject[
                    childrenName
                ] = renameTreeField(v[childrenName], {
                    childrenName,
                    retainOther,
                    nameMap,
                });
            } else {
                delete newObject[childrenName];
            }

            return newObject;
        })
        .filter((v) => v);
};

export const getStringSet = (str, split = '=') => {
    let out = {};

    if (!str) {
        return out;
    }

    let matched = str.match(/(<%.+?%>)/g);

    if (!matched || !matched.length) {
        return out;
    }
    for (let i = 0; i < matched.length; i++) {
        let itemStr = matched[i];

        itemStr = itemStr.substring(2, itemStr.length - 2);

        if(itemStr.includes('=')) {
            itemStr = itemStr.split('=');
        }else {
            itemStr = itemStr.split(split);
        }

        out[itemStr[0]] = itemStr[1] || true;
    }

    return out;
};

export const treeFilter = (data, handle, options, parentArray = []) => {
    let childrenName = (options && options.childrenName) || "children";
    let keepByZeroChild = (options && options.keepByZeroChild) || false;

    return data.map((item, index) => {

        if (item.label&&item.label.length>10)
            item.label=item.label.slice(0,20)+'...'
            let flag = handle(item, parentArray, index);
            let forceKeep = false;

            if (typeof flag === "object") {
                forceKeep = flag.forceKeep;
                flag = flag.flag;
            }

            if (!flag && !forceKeep) {
                return null;
            }

            let out = { ...item };
            if (out[childrenName] && out[childrenName].length) {
                let childrenList = treeFilter(
                    out[childrenName],
                    handle,
                    options,
                    parentArray.concat(out)
                );

                if (!forceKeep && !keepByZeroChild && !childrenList.length) {
                    return null;
                }

                out[childrenName] = childrenList;
            }
            return out;
        }).filter((v) => v);
};

export const getTreeTraceList = (
    id,
    tree,
    { idName = "id", childrenName = "children" } = {}
) => {
    for (let index = 0; index < tree.length; index++) {
        const element = tree[index];

        if (element[idName] === id) {
            return [element];
        }

        if (element[childrenName] && element[childrenName].length) {
            let result = getTreeTraceList(id, element[childrenName], {
                idName,
                childrenName,
            });

            if (result) {
                return [element, ...result];
            }
        }
    }

    return null;
};

export const traversalTree = (data, handle, options = {}, parentArray = []) => {
    let childrenName = options.childrenName || "children";

    return data.map((item, index) => {
        let out = handle(item, parentArray, index);

        if (item[childrenName] && item[childrenName].length) {
            let childrenList = traversalTree(
                item[childrenName],
                handle,
                options,
                parentArray.concat(item)
            );

            if (out) {
                out[childrenName] = childrenList;
            }
        }

        return out;
    });
};

export const addZero = (number, digit) => {
    return `${new Array(Math.max(digit - String(number).length, 0))
        .fill()
        .map(() => "0")
        .join("")}${number}`;
};
